package com.util_code.base;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Looper;

import androidx.annotation.NonNull;
import androidx.multidex.MultiDex;

import com.orhanobut.hawk.Hawk;
import com.util_code.dagger.component.AppComponent;
import com.util_code.dagger.component.DaggerAppComponent;
import com.util_code.dagger.module.AppModule;
import com.util_code.logger.ReleaseTree;
import com.util_code.utils.AndroidUtils;

import io.reactivex.Scheduler;
import io.reactivex.android.plugins.RxAndroidPlugins;
import io.reactivex.android.schedulers.AndroidSchedulers;
import timber.log.Timber;

public class BaseApplication extends Application {

    private static AppComponent mAppComponent;
    private static BaseAppManager mAppManager;

    @Override
    public void onCreate() {
        super.onCreate();

        AndroidUtils.init(this);

        Hawk.init(this).build();

        initAppInject(this);

        Timber.plant(new ReleaseTree());

        // RxAndroid Sets all Messages it handles to be asynchronous by default
        Scheduler asyncMainThreadScheduler = AndroidSchedulers.from(Looper.getMainLooper(), true);
        RxAndroidPlugins.setInitMainThreadSchedulerHandler(callable -> asyncMainThreadScheduler);
        // Or if the default scheduler is already initialiazed
        RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> asyncMainThreadScheduler);
    }

    public static BaseAppManager getAppManager() {
        if (mAppManager == null) {
            synchronized (BaseApplication.class) {
                if (mAppManager == null) {
                    mAppManager = BaseAppManager.getAppManager();
                }
            }
        }
        return mAppManager;
    }

    public void initAppInject(Context context) {
        mAppComponent = DaggerAppComponent.builder()
                .appModule(new AppModule((Application) context))
                .build();
    }

    public static AppComponent getAppComponent() {
        return mAppComponent;
    }

    @Override
    public void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        // you must install multiDex whatever tinker is installed!
        MultiDex.install(base);
    }

    public static void finishAllActivity() {
        mAppManager.finishAllActivity();
    }

    public static void exitApp() {
        mAppManager.AppExit();
    }

    public static void restartApp(@NonNull Activity activity) {
        Intent intent = activity.getPackageManager()
                .getLaunchIntentForPackage(activity.getPackageName());
        Class<? extends Activity> resolvedActivityClass;
        if (intent != null && intent.getComponent() != null) {
            try {
                resolvedActivityClass = (Class<? extends Activity>) Class.forName(intent.getComponent()
                        .getClassName());
                intent.setClass(activity, resolvedActivityClass);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                if (intent.getComponent() != null) {
                    //If the class name has been set, we force it to simulate a Launcher launch.
                    //If we don't do this, if you restart from the error activity, then press home,
                    //and then launch the activity from the launcher, the main activity appears twice on the backstack.
                    //This will most likely not have any detrimental effect because if you set the Intent component,
                    //if will always be launched regardless of the actions specified here.
                    intent.setAction(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                }
                activity.startActivity(intent);
                activity.finish();
                exitApp();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                //Should not happen, print it to the log!
            }
        }

    }

}
